package models

import (
	MysqlDB "gin-AssetManagement/inits/mysqlinit"
	"gin-AssetManagement/utils"
	"gorm.io/gorm"
	"time"
)

type Users struct {
	gorm.Model
	Name          string     `gorm:"comment:姓名;unique" json:"name" validate:"required" form:"name"`
	Roles         []Roles    `gorm:"many2many:users_roles;" json:"roles" form:"roles"`
	PassWord      string     `gorm:"comment:密码;unique" json:"passWord" validate:"required" form:"password"`
	Salt          string     `gorm:"comment:随机数密码校验" json:"salt" form:"salt"`
	Sex           uint8      `gorm:"comment:性别 0:女,1:男" json:"sex" form:"sex"`
	Age           uint8      `gorm:"comment:年龄" json:"age" form:"age"`
	Phone         string     `gorm:"comment:手机号;unique" json:"phone" validate:"required,customValidate" form:"phone"`
	Email         string     `gorm:"comment:邮箱" json:"email" validate:"required,email" form:"email"`
	ClientIp      string     `gorm:"comment:客户端Ip" json:"clientIp" form:"client_ip"`
	Status        int8       `gorm:"comment:状态" json:"status" form:"status"`
	CreatedUser   *Users     `gorm:"foreignKey:CreatedUserID" json:"created_user" form:"created_user"`
	CreatedUserID uint       `json:"created_user_id"`
	UpdatedUser   *Users     `gorm:"foreignKey:UpdatedUserID" json:"updated_user" form:"updated_user"`
	UpdatedUserID uint       `json:"updated_user_id"`
	LoginTime     *time.Time `gorm:"comment:登录时间" json:"loginTime" form:"loginTime"`
	LoginOutTime  *time.Time `gorm:"comment:登出时间" json:"loginOutTime" form:"loginOutTime"`
	DeviceInfo    string     `gorm:"comment:设备信息" json:"deviceInfo" form:"deviceInfo"`
}

var DB = MysqlDB.MysqlDB

// 自动迁移数据结构(table schema)自动创建表
// 注意:在gorm中，默认的表名都是结构体名称的复数形式，比如User结构体默认创建的表为users
// db.SingularTable(true) 可以取消表名的复数形式，使得表名和结构体名称一致
func init() {
	err := DB.AutoMigrate(&Users{})
	if err != nil {
		return
	}
}

// GetUserBasicById 根据ID查询用户
func (u *Users) GetUserBasicById() error {
	msg := DB.First(u)
	if msg.Error != nil {
		return msg.Error
	}
	return nil
}

// CreateUser 添加用户
func (u *Users) CreateUser() error {
	msg := DB.Create(u)
	if msg.Error != nil {
		return msg.Error
	}
	return nil
}

// QueryUserName 查询用户名
func (u *Users) QueryUserName() error {
	result := DB.Where("name = ?", u.Name).First(u)
	if result.Error != nil {
		return result.Error
	}
	return nil
}

// GetRoleIdByUserID 根据用户ID查询角色
func (u *Users) GetRoleIdByUserID() (rolesIds []uint, err error) {
	var user Users
	err = DB.Preload("Roles", func(db *gorm.DB) *gorm.DB {
		return db.Where("is_usable !=0")
	}).Take(&user, u.ID).Error
	if err != nil {
		return nil, err
	}
	for _, v := range user.Roles {
		rolesIds = append(rolesIds, v.ID)
	}
	return
}

// GetUserLists 获取用户集合
func GetUserLists(name, phone, status string, page, limit int) (users []Users, count int64, err error) {
	query := DB.Model(&Users{})
	if name != "" {
		query = query.Where("name = ?", name)
	}

	if phone != "" {
		query = query.Where("phone = ?", phone)
	}

	if status != "" {
		query = query.Where("status = ?", status)
	}

	if err = query.Preload("Roles").Preload("CreatedUser").Preload("UpdatedUser").Order("ID desc").Limit(limit).Offset((page - 1) * limit).Count(&count).
		Find(&users).Error; err != nil {
		return
	}

	return
}

// UpdateUserById 根据用户id更新用户信息
func UpdateUserById(id int, users Users) error {
	var u Users
	// 先查询
	if err := DB.First(&u, id).Error; err != nil {
		return err
	}
	// 执行事务更新操作
	return DB.Transaction(func(tx *gorm.DB) error {
		// 更新字段的值
		if err := tx.Model(&u).Updates(users).Error; err != nil {
			return err
		}
		// 更新用户和角色表的绑定
		if err := tx.Model(&u).Association("Roles").Replace(users.Roles); err != nil {
			return err
		}
		return nil
	})
}

func DelUserById(id int) error {
	// 根据角色ID查询角色
	var user Users
	if err4 := DB.First(&user, id).Error; err4 != nil {
		return err4
	}
	err := DB.Transaction(func(tx *gorm.DB) error {
		if err1 := tx.Delete(&user, id).Error; err1 != nil {
			return err1
		}
		// 清除用户和角色的关联
		if err2 := tx.Model(&user).Association("Roles").Replace([]Roles{}); err2 != nil {
			return err2
		}
		return nil
	})
	if err != nil {
		return err
	}
	return nil
}
func ResetPassword(id int) error {
	password := "123456"
	salt := utils.SaltGenerate()
	// 加密
	pwd := utils.Encryption(password, salt)

	return DB.Model(&Users{}).Where("id=?", id).Select("pass_word", "salt").Updates(Users{
		PassWord: pwd,
		Salt:     salt,
	}).Error
}
